package com.lambkit.spring.handler;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.lambkit.core.task.http.HttpWorkCenter;
import com.lambkit.servlet.LambkitServletContext;
import com.lambkit.spring.SpringLambkit;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

/**
 * @author yangyong(孤竹行)
 */
public class LambkitHandlerInterceptor implements HandlerInterceptor {

    private long startMili;

    private HttpWorkCenter workCenter;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //System.out.println("---------preHandle--------");
        if(workCenter == null) {
            workCenter =  SpringLambkit.getApp().context().getWorkCenter(HttpWorkCenter.class);
        }
        if(workCenter != null) {
            boolean flag = workCenter.handle(new LambkitServletContext(request, response));
            if(flag) {
                return false;
            }
        }
        // 非浏览器请求返回失败
        String userAgent = request.getHeader("user-agent");
        if (!StrUtil.isNotBlank(userAgent)) {
            return false;
        }
        // 拦截目标
        if (interceptorTarget(request)) {
            return true;
        }
        boolean flag = before(request, response, handler);
        List<String> consoleInfo = (List<String>) request.getAttribute("consoleInfo");
        if(consoleInfo!=null && consoleInfo.size() > 2) {
            println(request, "             " + this.getClass().getName(), false);
        } else {
            println(request, "Interceptor: " + this.getClass().getName(), false);
        }
        return flag;
    }

    //controller执行之后，且页面渲染之前调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //System.out.println("---------postHandle--------");
        // 拦截目标
        if (interceptorTarget(request)) {
            return;
        }
    }

    //页面渲染之后调用，一般用于资源清理操作
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //System.out.println("---------afterCompletion--------");
        // 拦截目标
        if (interceptorTarget(request)) {
            return;
        }
        after(request, response, handler, ex);
    }

    protected boolean interceptorTarget(HttpServletRequest request) {
        String target = request.getRequestURI();
        if (target.indexOf('.') != -1 && !target.startsWith("/druid")) {
            return true;
        }
        if(target.startsWith("/error")) {
            return true;
        }
        return false;
    }


    public void println(HttpServletRequest request, String info, boolean print) {
        List<String> consoleInfo = (List<String>) request.getAttribute("consoleInfo");
        if(consoleInfo==null) {
            consoleInfo = new ArrayList<>(5);
            request.setAttribute("consoleInfo", consoleInfo);
        }
        consoleInfo.add(info);
        if(print) {
            System.out.println(info);
        }
    }

    public void printConsole(HttpServletRequest request) {
        List<String> consoleInfo = (List<String>) request.getAttribute("consoleInfo");
        if(consoleInfo!=null) {
            for(String info : consoleInfo) {
                System.out.println(info);
            }
        }
    }

    public boolean before(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //System.out.println("---------preHandle--------");
        startMili = System.currentTimeMillis();// 当前时间对应的毫秒数
        // 打印请求信息
        List<String> consoleInfo = new ArrayList<>(5);
        String time = DateUtil.formatDateTime(new Date());
        System.out.println("Lambkit api report ----------" + time + "-------------------------------");
        //System.out.println("Api of [" + target + "]");
        //System.out.println("-----------------------------------------");
        String httpMethod = "Url        : " + request.getMethod() + " " + request.getRequestURI();
        //println(request, httpMethod, true);
        System.out.println(httpMethod);
        StringBuilder strb = new StringBuilder("Parameter  :");
        Enumeration<String> paraNames = request.getParameterNames();
        while (paraNames.hasMoreElements()){
            String name = paraNames.nextElement();
            strb.append(" " + name);
            strb.append("=");
            strb.append(request.getParameter(name));
        }
        //println(request, strb.toString(), true);
        System.out.println(strb.toString());
        //System.out.println("-----------------------------");
        //System.out.println("-------------------------------------------------------------------------------");
        return true;
    }

    public void after(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //System.out.println("---------afterCompletion--------");
        long endMili=System.currentTimeMillis();
        Integer spendTime = (int) (endMili-startMili);
        //System.out.println("-----------------------------");
        printConsole(request);
        System.out.println("-------------------------------------------------------------------------------");
        String target = request.getRequestURI();
        System.out.println("Api of [" + target + "] use time：" + spendTime + " ms");
        System.out.println();

    }
}
